#pragma once


namespace soft_renderer
{
	class Vector3;
	class Quaternion;

	class Matrix4
	{
	private:
		double data[16]; // 行主序

	public:
		Matrix4();
		Matrix4(const Matrix4& m);

		void set(double n11, double n12, double n13, double n14, double n21, double n22, double n23, double n24, double n31, double n32, double n33, double n34, double n41, double n42, double n43, double n44);
		void identity();
		void lookAt(Vector3 eye, Vector3 target, Vector3 up);
		void perspective(double fov, double aspect, double near, double far);
		void orthographic(double left, double right, double bottom, double top, double near, double far);
		void setTranslation(Vector3 v);
		void multiply(const Matrix4& m);
		void premultiply(const Matrix4& m);
		void multiplyMatrices(const Matrix4& a, const Matrix4& b);
		void compose(Vector3 position, Quaternion quaternion, Vector3 scale);
		void transpose();
		double determinant(); // 行列式
		void invert(); // 逆矩阵

		friend class Vector3;
	};

}
